今から始める Amazon Cognito 入門 #2:ID トークンとアクセストークンの違い
この記事は アノテーション株式会社 AWS Technical Support Advent Calendar 2024 | Advent Calendar 2024 - Qiita 14日目の記事です。
こんにちは! アノテーションの吉本です。
AWS のコンソール画面にアップデートがあり、見た目が大きく変わりました。
それに従い Cognito の操作方法も変わったので手を動かしながら Cognito に再入門していきたいと思います。
前回の記事は以下のリンクよりご確認ください。
初めに
主にこの記事の中では Cognito の提供する機能について記載を行っていきます。
一般的な用語については簡単に以下のような形式で適宜説明を行いますが、詳細については別記事や外部サイト等も合わせてご確認ください。
本記事のゴール
ID トークンとアクセストークンの違いを理解する
OAuth 2.0 と OpenID Connect
ID トークンとアクセストークンの説明を行う前に、それぞれのトークンの説明に必要となる OAuth 2.0 と OpenID Connect について簡単に説明します。
OAuth 2.0
OAuth 2.0 は, サードパーティーアプリケーションによるHTTPサービスへの限定的なアクセスを可能にする認可フレームワークである.
OAuth 2.0 とは上述の通り、認可を行うためのフレームワークとなります。
多くのアプリケーションに採用されており、こちらのフレームワークに従うことにより同じフレームワークを利用しているアプリケーションと連携して認可を行うことが可能です。
認可を行うためのフレームワークとなるため、OAuth 2.0 のみでは認証を行うことはできません。
OAuth 2.0 では認可にアクセストークンを利用します。
OpenID Connect(OIDC)
OpenID Connect 1.0 は, OAuth 2.0 [RFC6749] プロトコルの上にシンプルなアイデンティティレイヤーを付与したものである. このプロトコルは Client が Authorization Server の認証結果に基づいて End-User のアイデンティティを検証可能にする. また同時に End-User の必要最低限のプロフィール情報を, 相互運用可能かつ RESTful な形で取得することも可能にする.
OpenID Connect とは上述の通り、OAuth 2.0 に認証を行うことができるように機能を追加したフレームワークとなります。
OAuth 2.0 は認可を行うフレームワークのため、ユーザーの識別を行う認証を行う機能はありませんでしたが、OpenID Connect を利用することにより認証も実施することが可能になります。
OpenID Connect ではアクセストークンに加えて ID トークンを利用します。
Cognito ユーザープールでの扱いについて
ユーザープールドメインは、ユーザー認証、サードパーティープロバイダーとのフェデレーション、および OpenID Connect (OIDC) フローの機能をホストします。
Cognito ユーザープールでは上述のフレームワークが採用されており、フレームワークに従ったトークンが取得可能です。
また、ドメインを付与することにより Cognito ユーザープールを利用して OpenID Connect のフローを実装することが可能になります。
それでは、早速 ID トークン、アクセストークンを取得して中身を確認していきます。
やってみる
アクセストークンと ID トークンの取得については前回記事と同様にこちらの API を利用します
AWS CLI を用いたコマンドは以下です。
$ aws cognito-idp admin-initiate-auth \
--user-pool-id {ユーザープール ID} \
--client-id {クライアント ID} \
--auth-flow "ADMIN_USER_PASSWORD_AUTH" \
--auth-parameters USERNAME={メールアドレス},PASSWORD={パスワード}
Cognito ユーザープールから返却される ID トークン、アクセストークンは JSON Web Token (JWT) という形式です。
また、下記のドキュメントに記載されているように Base64 エンコードされた文字列なので、デコードすることで人間が読むことのできる JSON 文字列に変換できます。
アクセストークン・ID トークンは「.」によって 3 つのセクションに分けられており、一つ目がヘッダー、二つ目がペイロード、三つ目が署名となっています。
三つ目の署名はデコード可能な文字列ではないため、今回はヘッダーとペイロードをデコードして確認していきます。
A JSON Web Token (JWT) includes three sections with a . (dot) delimiter between them.
(中略)
Signature
The signature isn't decodable base64url like the header and payload. It's an RSA256 identifier > derived from a signing key and parameters that you can observe at your JWKS URI.The header and payload are base64url-encoded JSON.
今回、デコードの手順には下記のブログを参考にさせていただきました!
では実際にデコードして中身を見ていきます。
アクセストークン
ヘッダー
$ ACCESS_TOKEN={アクセストークン}
$ echo ${ACCESS_TOKEN} | cut -d'.' -f 1 | base64 -D
{"kid":"6dhW...","alg":"RS256"}
ペイロード
$ ACCESS_TOKEN={アクセストークン}
$ echo ${ACCESS_TOKEN} | cut -d'.' -f 2 | base64 -D
{
"sub":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"iss":"https:\/\/cognito-idp.ap-northeast-1.amazonaws.com\/ap-northeast-1_XXXXXXXXX",
"client_id":"XXXXXXXXXXXXXXXXXXXXXXXXXX",
"origin_jti":XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"event_id":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"token_use":"access",
"scope":"aws.cognito.signin.user.admin",
"auth_time":1733734629,"exp":1733738229,
"iat":1733734629,
"jti":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"username":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
結果は上記のようになりました。
最低限のユーザー情報に加え、token_use
が access
となっていることが確認できます。
各項目の詳細については下記のドキュメントをご覧ください。
実際のアプリケーションではこの値や署名を確認し、アクセストークンが正しいものかを検証します。
検証は独自の実装を行っていただくことも可能ですが、JavaScript で実装されているアプリケーションの場合 AWS の提供する aws-jwt-verify をご利用いただくことで容易に実装が可能です。
また、Cognito 独自のアクセストークンの利用方法としてユーザー情報の更新やユーザーの削除のために利用される、Cognito ユーザープール API の呼び出しにも必要になります。
AccessToken
A valid access token that Amazon Cognito issued to the user whose user attributes you want to update.
続いて ID トークンも見ていきます。
ID トークン
ヘッダー
$ ID_TOKEN={ID トークン}
$ echo ${ID_TOKEN} | cut -d'.' -f 1 | base64 -D
{"kid":"kpbV3...","alg":"RS256}
ペイロード
$ ID_TOKEN={ID トークン}
$ echo ${ID_TOKEN} | cut -d'.' -f 2 | base64 -D
{
"sub":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"email_verified":false,
"iss":"https:\/\/cognito-idp.ap-northeast-1.amazonaws.com\/ap-northeast-1_XXXXXXXXX",
"cognito:username":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"origin_jti":"XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"aud":"XXXXXXXXXXXXXXXXXXXXXXXXXX",
"event_id":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"token_use":"id",
"auth_time":1733734629,
"exp":1733738229,
"iat":1733734629,
"jti":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"email":"XXXXX@XXXXX.XX"
}
先ほどのアクセストークンは認可のためのトークンとなるため最低限のユーザー情報のみとなりますが、ID トークンはユーザーの特定ができるように email 属性などより細かいユーザー情報が付与されていることが確認できます。
各項目の詳細については下記のドキュメントをご確認ください。
ID トークンをご利用いただくことで、アプリケーションからユーザーの特定が可能となりアクセストークン利用時に懸念されるなりすましなどのリスクを軽減することが可能です。
(おまけ) リフレッシュトークン
You can use the refresh token to retrieve new ID and access tokens.
ID トークン、アクセストークンには有効期限が設定されており、一定期間経過すると利用ができなくなります。
利用できなくなったトークンは再度サインインすることでも取得可能ですが、リフレッシュトークンを利用することで、ユーザー操作を介さず新しいトークンを取得することが可能です。
リフレッシュトークンはクライアント側でデコードや検証を行うことはできず、Cognito ユーザープール側でのみ検証が実施されます。
以上、Cognito ユーザープールで利用されるトークンについて確認を行いました。
まとめ
- ID トークンは認証の結果取得できるトークンでユーザー属性等が格納されている
- アクセストークンは認可の結果取得できるトークンで最低限のユーザー情報のみが格納されており、Cognito ユーザープール API の呼び出しに必要になる。
- リフレッシュトークンは有効期限の切れた ID トークン・アクセストークンの更新に利用できる。
参考資料
- The OAuth 2.0 Authorization Framework
- Final: OpenID Connect Core 1.0 incorporating errata set 1
- ユーザープールのドメインを設定する - Amazon Cognito
- 今から始める Amazon Cognito 入門 #1:ユーザープールと ID プールの違い | DevelopersIO
- AdminInitiateAuth - Amazon Cognito User Pools
- JSON Web Tokens - jwt.io
- Verifying a JSON Web Token - Amazon Cognito
- Cognitoのサインイン時に取得できる、IDトークン・アクセストークン・更新トークンを理解する | DevelopersIO
- Understanding the access token - Amazon Cognito
- Cognito JSON ウェブトークンの署名をデコードして検証する | AWS re:Post
- UpdateUserAttributes - Amazon Cognito User Pools
- Understanding the identity (ID) token - Amazon Cognito
- Understanding the refresh token - Amazon Cognito
アノテーション株式会社について
アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。